<template>
  <view class="m-form-c">
    <m-form-item
      v-for="item in formatOption.column"
      :label="item.label"
      :required="item.required"
      :key="item.prop"
    >
      <!-- 输入框 -->
      <m-input
        v-if="
          !item.type ||
          item.type === 'text' ||
          item.type === 'number' ||
          item.type === 'idcard' ||
          item.type === 'digit'
        "
        :placeholder="item.placeholder || `请输入${item.label}`"
        :value="value[item.prop]"
        :type="item.type || 'text'"
        :disabled="item.disabled || false"
        :password="item.password || false"
        :focus="item.focus || false"
        :maxlength="item.maxlength || -1"
        :confirmType="item.confirmType"
        @input="updateValue($event, item)"
      >
      </m-input>
      <!-- 选择器 -->

      <m-picker
        v-if="
          item.type === 'date' ||
          item.type === 'year' ||
          item.type === 'month' ||
          item.type === 'time' ||
          item.type === 'select'
        "
        :mode="item.mode || 'date'"
        :placeholder="item.placeholder || `请选择${item.label}`"
        :disabled="item.disabled || false"
        :start="item.start"
        :end="item.end"
        :fields="item.fields"
        :value="getPickerValue(item)"
        :range="item.dicData || []"
        :rangeKey="item.rangeKey"
        @input="updateValue($event, item)"
      ></m-picker>

      <!-- 选择地址 -->
      <m-map
        v-if="item.type === 'map'"
        :placeholder="item.placeholder || `请选择${item.label}`"
        :value="value[item.prop]"
        @input="updateValue($event, item)"
      ></m-map>

      <!-- 图片上传 -->
      <m-upload-list
        v-if="item.type === 'upload'"
        :value="value[item.prop] || []"
        :bgColor="item.bgColor || '#f8f8f8'"
        :size="item.size || '138rpx'"
        :count="item.count || 10"
        @input="updateValue($event, item)"
      >
      </m-upload-list>

      <!-- 开关 -->
      <view class="flex-center m-form-switch" v-if="item.type === 'switch'">
        <m-switch
          size="42rpx"
          :disabled="item.disabled"
          :value="value[item.prop] === undefined ? 1 : value[item.prop]"
          @input="updateValue($event, item)"
        >
        </m-switch>
      </view>
	  
	  <!-- 多行输入框 -->
	  <m-textarea
	    v-if="item.type === 'textarea'"
	    :placeholder="item.placeholder || `请输入${item.label}`"
	    :value="value[item.prop]"
	    :disabled="item.disabled || false"
	    :focus="item.focus || false"
	    :maxlength="item.maxlength || -1"
	    :confirmType="item.confirmType"
	    @input="updateValue($event, item)"
	  >
	  </m-textarea>
    </m-form-item>
  </view>
</template>

<script>
export default {
  name: "m-form",
  props: {
    option: {
      type: Object,
      default: () => {
        return {
          column: [],
        };
      },
    },
    value: {
      type: Object,
      default: () => {
        return {};
      },
    },
  },
  computed: {
    formatOption() {
      let option = this.$m.deepClone(this.option);
      option.column.map((item) => {
        switch (item.type) {
          case "date":
          case "year":
          case "month":
          case "time":
          case "select":
            const { mode, fields, rangeKey } = this.getPickerProps(item);
            item.mode = mode;
            item.fields = fields;
            item.rangeKey = rangeKey;
            break;
          default:
            break;
        }
      });
      return option;
    },
  },
  methods: {
    getPickerValue(item) {
      const { type, prop, dicData, props } = item;
      let value = this.value[prop];
      switch (type) {
        case "select":
          if (value !== undefined) {
            const formatSelectValue = this.value[`$_index_${prop}`];
            if (formatSelectValue !== undefined) {
              value = formatSelectValue;
            } else {
              value =
                "" +
                dicData.findIndex(
                  (cItem) =>
                    cItem[(props && props.value) || "value"] ===
                    this.value[prop]
                );
              this.updateValue(value, item);
            }
          }
          break;
        default:
          break;
      }
      return value;
    },
    getPickerProps(item) {
      const { type, prop, props } = item;
      let pickerProps = {
        mode: type,
        fields: "day",
      };
      switch (type) {
        case "year":
          pickerProps = {
            mode: "date",
            fields: "year",
          };
          break;
        case "month":
          pickerProps = {
            mode: "date",
            fields: "month",
          };
          break;
        case "select":
          pickerProps = {
            mode: "selector",
            rangeKey: (props && props.label) || "label",
          };
          break;
        default:
          break;
      }
      return pickerProps;
    },
    updateValue(val, item) {
      const { prop, props, type, dicData, rangeKey } = item;
      switch (type) {
        case "select":
          this.$emit("input", {
            ...this.value,
            [prop]: dicData[val][(props && props.value) || "value"],
            [`$_label_${prop}`]: dicData[val][rangeKey],
            [`$_index_${prop}`]: val,
          });
          break;
        case "map":
          const [name, address, longitude, latitude] = val;
          this.$emit("input", {
            ...this.value,
            [prop]: address,
            [`$_addrName_${prop}`]: name,
            [`$_addrLongitude_${prop}`]: longitude,
            [`$_addrLatitude_${prop}`]: latitude,
          });
          break;
        default:
          this.$emit("input", {
            ...this.value,
            [prop]: val,
          });
          break;
      }
    },
    getErrMsg(item) {
      let msg = "";
      switch (item.type) {
        case "date":
        case "year":
        case "month":
        case "time":
        case "select":
          msg = `请选择${item.label}`;
          break;
        default:
          msg = `请输入${item.label}`;
          break;
      }
      return msg;
    },
    validate(cb) {
      let errMsg;
      this.formatOption.column.map((item) => {
        if (errMsg) return;
        if (
          item.required &&
          (!this.value[item.prop] || !("" + this.value[item.prop]).trim())
        ) {
          errMsg = item.placeholder || this.getErrMsg(item);
        }
      });
      errMsg &&
        uni.showToast({
          title: errMsg,
          icon: "none",
        });
      cb(!errMsg);
    },
  },
};
</script>

<style lang="scss" scoped>
.m-form {
  &-c {
    width: 100%;
    background-color: #ffffff;
    border-radius: 10rpx;
    overflow: hidden;
  }

  &-switch {
    // flex: 1;
    height: 100rpx;
    justify-content: flex-end;
  }
}
</style>
